﻿Public Class Config
    ''' <summary>
    ''' Checks, creates and returns path to the application config file
    ''' </summary>
    Public Shared Function GetConfigFilepath() As String
        Dim UserDataPath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
        Dim AppDataPath = IO.Path.Combine(UserDataPath, "gstartup")
        If Not IO.Directory.Exists(AppDataPath) Then
            IO.Directory.CreateDirectory(AppDataPath)
        End If
        Return IO.Path.Combine(AppDataPath, "gstartup.cfg")
    End Function

    ''' <summary>
    ''' Reads time list from config file
    ''' </summary>
    ''' <returns>AppScheduler object</returns>
    Public Shared Function ReadScheduler() As AppScheduler
        Const SECTION_PROGRAM As String = "PROGRAM"
        Const SECTION_STARTUP As String = "STARTUP"

        Dim scheduler As New AppScheduler()

        Dim configpath As String = GetConfigFilepath()
        If Not IO.File.Exists(configpath) Then
            Return scheduler
        End If

        Dim lines As String() = IO.File.ReadAllLines(configpath)

        Dim cur_section As String = ""

        For Each line As String In lines
            line = line.Trim()
            If line = "" Then
                'empty line, do nothing
            ElseIf line.StartsWith("#") Then
                'it's a comment, do nothing
            ElseIf line.EndsWith(":") Then
                'it's a section header
                cur_section = line.Substring(0, line.Length - 1).ToUpper
            Else
                If cur_section = SECTION_PROGRAM Then
                    'do nothing yet
                ElseIf cur_section = SECTION_STARTUP Then
                    Dim time As TimeDef = LineToTime(line)
                    If Not time Is Nothing Then
                        scheduler.Push(time)
                    End If
                End If
            End If
        Next

        Return scheduler
    End Function

    ''' <summary>
    ''' Converts a string to a TimeDef object
    ''' </summary>
    Private Shared Function LineToTime(ByVal line As String) As TimeDef
        'split string by spaces but ignore spaces within quotes
        Try
            Dim values As String() = SplitIgnoreInQuotes(line)
            'valid lines have 3 properties, offset, name and path
            If values.Length >= 3 Then
                Dim offset As String = values(0)
                Dim name As String = values(1)
                Dim path As String = values(2)
                Dim args(values.Length - 4) As String
                For i As Integer = 3 To values.Length - 1
                    args(i - 3) = values(i)
                Next
                Dim time As New TimeDef(name, CInt(offset), path, args)
                Return time
            Else
                Debug.WriteLine("Wrong timedef: " + line)
                Return Nothing
            End If
        Catch ex As UnclosedQuotation
            'write somewhere
            Debug.WriteLine(ex.Message)
            Return Nothing
        End Try
    End Function

    Private Shared Function SplitIgnoreInQuotes(ByVal value As String) As String()
        Dim charcount As Integer = value.Length
        Dim InQuote As Boolean = False
        Dim retValues As New List(Of String)
        Dim CurString As String = ""
        For cc As Integer = 0 To charcount - 1
            If value(cc) = """" Then
                If InQuote Then
                    If CurString <> "" Then
                        retValues.Add(CurString)
                        CurString = ""
                    End If
                End If
                InQuote = Not InQuote
            Else
                If InQuote Then
                    CurString &= value(cc)
                Else
                    If value(cc) = " " Then
                        If CurString <> "" Then
                            retValues.Add(CurString)
                            CurString = ""
                        End If
                    Else
                        CurString &= value(cc)
                    End If
                End If
            End If
        Next
        If InQuote Then
            Throw New UnclosedQuotation("Unclosed quotation marks in '" & value & "'")
        End If
        If CurString <> "" Then
            retValues.Add(CurString)
        End If
        Return retValues.ToArray
    End Function
End Class

